package com.qjq.glasses_shopping.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

//security配置类
@Configuration
//开启鉴权注解
@EnableMethodSecurity
public class SecurityConfig {
    @Bean
    protected SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //自定义表单登录
        http.formLogin(
                form -> {
                    form.usernameParameter("username")//用户名
                        .passwordParameter("password")//密码
                        .loginPage("/admin/login")//登录提交路径
                        .successHandler(new MyLoginSuccessHandler())//登陆成功处理器
                        .failureHandler(new MyLoginFailureHandler());//登录失败处理器
                }
        );
        //权限拦截配置
        http.authorizeRequests(
                resp -> {
                    //登录不需要认证
                    resp.requestMatchers("/login","/admin/login").permitAll();
                    resp.requestMatchers("/user/**").permitAll();//放行前台
                    resp.anyRequest().authenticated();//其他的请求需要认证
                }
        );
        //退出登录配置
        http.logout(
                logout -> {
                    logout.logoutUrl("/admin/logout")//退出路径
                            .logoutSuccessHandler(new MyLogoutSuccessHandler())//退出登录处理器
                            .clearAuthentication(true)//清除认证信息
                            .invalidateHttpSession(true);//清除session
                }
        );
        //异常处理配置
        http.exceptionHandling(
                exception -> {
                    exception.accessDeniedHandler(new MyAccessDeniedHandler())//权限不足处理器
                        .authenticationEntryPoint(new MyAuthenticationEntryPoint());//未登录处理器

                }
        );
        //设置跨域
        http.csrf();
        //关闭csrf防护
        http.csrf(
                csrf -> {
                    csrf.disable();
                });
        return http.build();
    }

    //加密工具
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
